class Deliverable < ActiveRecord::Base
  belongs_to :schedulable, :polymorphic => true
  has_many :assignments, :dependent => :destroy
  belongs_to :feature
  belongs_to :project
  belongs_to :product


  validates_presence_of :description, :feature_name, 
    :project_name, :product_name

  STATUS_CODES = {
    0 => 'Complete',
    1 => 'Moved to next iteration',
    2 => 'Deferred',
    3 => 'Moved to open issues',
    4 => 'Canceled'
  }

  def to_open_issue
    OpenIssue.new :description => self.description,
      :comments => self.comments
  end

  def Deliverable.status_codes
    STATUS_CODES
  end

  def status
    STATUS_CODES[status_id] || ''
  end

  def status=(value)
    self.status_id = STATUS_CODES.invert[value]
  end

  def resource_names
    self.assignments.collect { |assignment| assignment.resource.name }
  end

  def resource_names=(value)

    # get the resources that match the resource names
    assigned_resources = Resource.resources(value)

    # assign the resources to this deliverable
    self.assignments.clear
    self.assignments << assigned_resources.collect do |resource|
      assignment = Assignment.new
      assignment.deliverable = self
      assignment.resource = resource
      assignment
    end
  end

  def resource_names_csv
    self.resource_names.collect { |name| Resource.format_name(name) }.join(', ')
  end

  def resource_names_csv=(value)
    self.resource_names = value.split(',').collect { |n| n.strip }
  end

  def feature_name
    self.feature.name unless self.feature == nil
  end

  def feature_name=(value)
    self.feature = Feature.get(value)
    self.feature.name = value
  end

  def project_name
    self.project.name unless self.project == nil
  end

  def project_name=(value)
    self.project = Project.get(value)
    self.project.name = value
  end

  def product_name
    self.product.name unless self.product == nil
  end

  def product_name=(value)
    self.product = Product.get(value)
    self.product.name = value
  end

  # Creates and returns a deep copy/clone of this deliverable
  # Since 'clone' only does a shallow copy
  # we need to manually go copy the
  # assignments
  def deep_clone

    #clone the deliverable
    cloned_deliverable = self.clone

    cloned_deliverable.assignments = Array.new

    # clone each assignment
    self.assignments.each do |assignment|
      cloned_assignment = assignment.clone
      cloned_assignment.deliverable = cloned_deliverable
      cloned_deliverable.assignments << cloned_assignment
    end

   cloned_deliverable 
  end

 def Deliverable.sort_deliverables(deliverables)
    sorted_deliverables = deliverables.sort_by { 
      |a| [ a.project_name.downcase, a.product_name, a.feature_name.downcase, a.description ] 
    }
    sorted_deliverables 
  end

end
